package com.eCommerce.server.dao.impl;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;



import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;


import com.eCommerce.corecontract.criteria.UserCriteria;
import com.eCommerce.corecontract.dto.ComposantDTO;
import com.eCommerce.corecontract.dto.LigneCommandeDTO;
import com.eCommerce.corecontract.dto.UserDTO;
import com.eCommerce.corecontract.exception.EcommerceException;
import com.eCommerce.corecontract.exception.EcommercePersisenceException;
import com.eCommerce.server.corebackend.dao.AbstractCommonHibernateDAO;
import com.eCommerce.server.corebackend.dao.IUserDAO;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.transaction.support.TransactionSynchronizationManager;

public class UserDAOImpl extends AbstractCommonHibernateDAO implements IUserDAO{
	
	public UserDAOImpl()
	{
		super();
		/* if (!TransactionSynchronizationManager.isSynchronizationActive())
			   TransactionSynchronizationManager.initSynchronization();*/
	}

	private static Logger log =Logger.getLogger(UserDAOImpl.class.getName());

	public void delete(UserDTO userDTO) throws EcommerceException {
		// TODO Auto-generated method stub
		
		try {
			Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
			   String hql = "delete from UserDTO where id = :id";
		        Query query = session.createQuery(hql);
		        
		        query.setLong("id",userDTO.getId());
		        int rowCount = query.executeUpdate();
			this.getHibernateTemplate().delete(userDTO);
		} catch (DataAccessException e) {
			Object[] arg=new Object[1];
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-005",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
		
	}


	public List find(UserCriteria userCriteria)
			throws EcommerceException {
	
		try {
			Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(UserDTO.class);
			if (userCriteria.getRole() != null){
				// Case isensitive search
				crit.add(Expression.ilike("role", userCriteria.getRole()));
			}
			if (userCriteria.getNom() != null){
				// Case isensitive search
				crit.add(Expression.ilike("nom", userCriteria.getNom()));
			}
			if (userCriteria.getPrenom() != null){
				// Case isensitive search
				crit.add(Expression.ilike("prenom", userCriteria.getPrenom()));
			}
			if (userCriteria.getLogin() != null){
				// Case isensitive search
				crit.add(Expression.ilike("login", userCriteria.getLogin()));
			}
			if (userCriteria.getEmail() != null){
				// Case isensitive search
				crit.add(Expression.ilike("email", userCriteria.getEmail()));
			}
			if (userCriteria.getId() != null){
				// Case isensitive search
				crit.add(Expression.ilike("id", userCriteria.getId()));
			}
			return crit.list();
			//UserDTO user = (UserDTO)crit.uniqueResult();
			//return (user != null);
			
		} catch (Exception e) {
			Object[] arg=new Object[1];
			
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-004",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
		
	}


	public UserDTO findOne(UserDTO userDTO) throws EcommerceException {
		// TODO Auto-generated method stub
		
		try {
			userDTO = (UserDTO)this.getHibernateTemplate().get(UserDTO.class, userDTO.getId());
		} catch (DataAccessException e) {
			Object[] arg=new Object[1];
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-003",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
		return userDTO;
	}

	public Long insert(UserDTO userDTO) throws EcommerceException {
		// TODO Auto-generated method stub

		try {
			
			this.getHibernateTemplate().save(userDTO);
		} catch (DataAccessException e) {
			Object[] arg=new Object[1];
			arg[0] = userDTO.getNom();
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-001",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
		return userDTO.getId();
	}


	public void update(UserDTO userDTO) throws EcommerceException {
		// TODO Auto-generated method stub
		
		try {
			this.getHibernateTemplate().update(userDTO);
			getHibernateTemplate().getSessionFactory().getCurrentSession().flush(); 
			getHibernateTemplate().getSessionFactory().getCurrentSession().clear();
			
		} catch (DataAccessException e) {
			Object[] arg=new Object[1];
			arg[0] = userDTO.getNom();
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-002",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
		
	}


	public List findAll() throws EcommerceException {
		try {
			
			return this.getHibernateTemplate().executeFind(new HibernateCallback() {
				public Object doInHibernate(Session session)
					throws HibernateException, SQLException {

					StringBuffer sb = new StringBuffer(100);
					sb.append("select distinct user ");
					sb.append("from Users user ");
					sb.append("order by user.id");

					Query query = session.createQuery(sb.toString());
					List list = query.list();

					return list;
				}
			});	
		
		} catch (DataAccessException e) {
			Object[] arg=new Object[1];
			
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-004",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
	}


	public boolean checkLogin(String login, String password)
			throws EcommerceException 
			
	{
		try {
			logger.info("Check user with login: "+login+" and password : [PROTECTED]");

			
			Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(UserDTO.class);
			if (login != null){
				// Case isensitive search
				crit.add(Expression.ilike("login", login));
			}
			crit.add(Expression.eq("password", password));
			
			UserDTO user = (UserDTO)crit.uniqueResult();
			return (user != null);
		}
		catch(DataAccessException e) {
			// Critical errors : database unreachable, etc.
			
			logger.error("Exception - DataAccessException occurs : "+e.getMessage()
					+" on complete checkLogin().");
			return false;
		}
	}


	public UserDTO getUser(String login) throws EcommerceException  {
		// TODO Auto-generated method stub
		try {
			logger.info("get User with login: "+login);

			 if (!TransactionSynchronizationManager.isSynchronizationActive())
				   TransactionSynchronizationManager.initSynchronization();
			Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(UserDTO.class);
			UserDTO user=null;
			if (login != null){
				// Case isensitive search
				crit.add(Expression.eq("login", login));
				 user = (UserDTO )crit.uniqueResult();
			}
			
			
			return user;
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			Object[] arg=new Object[1];
			arg[0] = login;
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-006",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
	}
	
	public UserDTO getUserByEmail(String email) throws EcommerceException  {
		// TODO Auto-generated method stub
		try {
			logger.info("get User with email: "+email);
			

			 if (!TransactionSynchronizationManager.isSynchronizationActive())
				   TransactionSynchronizationManager.initSynchronization();
			Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
			// create a new criteria
			Criteria crit = session.createCriteria(UserDTO.class);
			UserDTO user=null;
			if (email != null){
				// Case isensitive search
				crit.add(Expression.eq("email", email));
				 user = (UserDTO )crit.uniqueResult();
			}
			
			
			return user;
		} catch (HibernateException e) {
			// TODO Auto-generated catch block
			Object[] arg=new Object[1];
			arg[0] = email;
			EcommercePersisenceException persistenceException=new EcommercePersisenceException(messagesXmlFileName,"ECOMMERCEDAOUSER-007",arg,e.getMessage());
			log.error(persistenceException.getMessage());
			throw persistenceException;
		}
	}
	}


